package com.wb.utils

import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import javax.script.ScriptEngineManager
import kotlin.collections.HashMap

/**
 * 黄历
 *
 * @author 祁雪
 */
open class ZodiacUtil {

    companion object {
        // 黄历原始数据存储
        val SOURCE_MAP = hashMapOf<String, String>()

        var sync_lock_gethl = false

        /**
         * 获取
         */
        fun getApiUrl(
            callback: String,
            date: String,
            year: String
        ): String {
            var url =
                "https://open.onebox.so.com/dataApi?callback=$callback&" +
                        "query=黄历&url=date:${date}|val:|cate:query|sub_cate:&type=calendar&asynLoading=1&" +
                        "src=onebox&year=${year}&num=1&keyword=date:${date}|val:|cate:query|sub_cate:"
            return url
        }

        fun getYear(): String {

            val date = Date()
            val gc = Calendar.getInstance() as GregorianCalendar
            gc.time = date
            val year = Integer.valueOf(gc[1])
            return year.toString()
        }

        fun parsingSourceJS() {
            val year = getYear()

            val result = RestUtil.send(
                getApiUrl(
                    "",
                    SimpleDateFormat("yyyyMMdd").format(Date()), year.toString()
                ), null, null, 0, String::class.java
            ).body

            val gson = Gson()

            var map = gson.fromJson(result, Map::class.java)

            println(map)

            map = gson.fromJson(gson.toJson(map.get("display")), Map::class.java)
            map = gson.fromJson(gson.toJson(map.get("rili")), Map::class.java)
            gson.fromJson(gson.toJson(map.get("huangli")), Map::class.java)
                .forEach { k, v ->
                    SOURCE_MAP.put(k.toString(), v!!.toString())
                }

            println("得到黄历运势源数据列成功: ${SOURCE_MAP}")

//            getHuangLiData(year.toString(), SimpleDateFormat("MMdd").format(Date()))


        }

        /**
         * 获取黄历数据 前提是 SOURCE_MAP 含有数据
         *
         * @param year 年份
         * @param date MMdd 用作js内json key
         */
        fun getHuangLiData(
            year: String,
            date: String
        ): HashMap<String, String>? {

            val key = "${date}-yun"

            val flag = WYMusicUtil.redisTemplate.hasKey(key)
            if (flag) {
                val map = Gson().fromJson(
                    WYMusicUtil.redisTemplate.opsForValue().get(date + "-yun").toString(),
                    object : TypeToken<HashMap<String, String>>() {}.type
                ) as HashMap<String, String>
                return map
            }

            if (!SOURCE_MAP.containsKey(year)) {
                return null;
            }

            if (sync_lock_gethl) {
                return null
            }

            sync_lock_gethl = true

            val result = RestUtil.send(SOURCE_MAP.get(key = year)!!, null, null, 0, String::class.java).body
            println("创建JS解析器")

            val manager = ScriptEngineManager();
            // 获取js引擎
            val engine = manager.getEngineByName("JavaScript");

            val js = "function get(){" +
                    "var data = {d0101${
                        result?.replace(
                            regex = Regex("\\s|.*?(d0101)"),
                            ""
                        )
                    };" +
                    "return JSON.stringify(data['d${date}'])}; get();"

            val data = engine.eval(js);

            println("今日运势: ${data}")

            val resultMap = Gson().fromJson(
                data.toString(),
                object : TypeToken<HashMap<String, String>>() {}.type
            ) as HashMap<String, String>

            WYMusicUtil.redisTemplate.opsForValue().set(key, data.toString())
            WYMusicUtil.redisTemplate.expire(key, 1, TimeUnit.DAYS)

            sync_lock_gethl = false
            return resultMap
        }
    }

}

fun main() {
    ZodiacUtil.parsingSourceJS()
}